/**
 * NODE = 0 --> guter weg
 * NODE = 20 --> schlechter weg
 * */
package de.hsb.ai.agent.misterx.pathheuristic;

import jade.core.AID;
import java.awt.Polygon;
import java.util.HashMap;
import java.util.List;
import de.hsb.ai.agent.misterx.brain.Brain;
import de.hsb.ai.agent.misterx.brain.GraphAnalyser.DangerZone;
import de.hsb.ai.agent.misterx.pathfinding.Node;


public class WeightHeuristic implements INodeHeuristic {
	
	private int DEFAULT_HEURISTIC 					= 1;
	private int HEURISTIC_FACTOR_CONVEX 			= 100;
	private int HEURISTIC_FACTOR_ENEMIES_RADIUS		= 100;
	private int HEURISTIC_FACTOR_ENEMIES_DIRECTION	= 100;
	
	
	private HashMap<Integer, Integer> _allNodes; // <nodeId, heuristic>
	
	public WeightHeuristic() {		
		this._allNodes = new HashMap<Integer, Integer>();
		for (int i = 1; i <= 199; i++) {
			this._allNodes.put(i, this.DEFAULT_HEURISTIC);
		}
	}
	
	
	@Override
	public int getHeuristik(Node startNode, Node endNode, Node currentNode) {
		
		if (this._allNodes == null || this._allNodes.size() == 0) {
			return this.DEFAULT_HEURISTIC;
		}
		
		return this._allNodes.get(currentNode._index);
		
	}

	@Override
	public void update() {
			
		this.analyzeConvexHull();
		
		this.analyzeEnemiesRadius();
		
		this.analyzeEnemiesDirection();
		
	}


	private void analyzeConvexHull() {
		if (!Brain.isEnemyMulti()) {
			return;
		}
		
		Polygon polygon = Brain.GEOANALYSER.getCurrentConvexHull();

		for (int nodeIndex : this._allNodes.keySet()) {
			if ( Brain.GEOANALYSER.isInPolygon(nodeIndex, polygon) ) {
				int weight = this._allNodes.get(nodeIndex);				
				this._allNodes.put(nodeIndex, weight + this.HEURISTIC_FACTOR_CONVEX);
			}
		}
	}


	private void analyzeEnemiesRadius() {
		/*
		for (int nodeIndex : this._allNodes.keySet()) {
			
			ArrayList<DangerZone> dangerZoneList = Brain.GRAPHANALYSER.getDangerZonesByNodeIndex(nodeIndex);
			
			for (DangerZone dangerZone : dangerZoneList) {
				
				for (AID aid : Brain.getEnemyAIDs()) {
					
					if (aid == dangerZone._aid) {
						int oldWeight = this._allNodes.get(nodeIndex);
						int newWeight = 0;
						
						switch (dangerZone._radius) {
							case 0:
								newWeight = oldWeight + 4 * this.HEURISTIC_FACTOR_ENEMIES_RADIUS;
								this._allNodes.put(nodeIndex, newWeight);
								break;
							case 1: 
								newWeight = oldWeight + 3 * this.HEURISTIC_FACTOR_ENEMIES_RADIUS;
								this._allNodes.put(nodeIndex, newWeight);
								break;
							case 2: 
								newWeight = oldWeight + 2 * this.HEURISTIC_FACTOR_ENEMIES_RADIUS;
								this._allNodes.put(nodeIndex, newWeight);
								break;
							case 3:
								newWeight = oldWeight + this.HEURISTIC_FACTOR_ENEMIES_RADIUS;
								this._allNodes.put(nodeIndex, newWeight);
								break;
						}
					}
				}
			}
		}*/
		
		for (AID aid : Brain.getEnemyAIDs()) {
			List<DangerZone> dangerZoneList = Brain.GRAPHANALYSER.getDangerZonesByAid(aid);
			
			for (DangerZone dangerZone : dangerZoneList) {
				int nodeIndex = dangerZone._move.getNode();
				
				int oldWeight = this._allNodes.get(nodeIndex);
				int newWeight = 0;
				
				switch (dangerZone._radius) {
					case 0:
						newWeight = oldWeight + 4 * this.HEURISTIC_FACTOR_ENEMIES_RADIUS;
						this._allNodes.put(nodeIndex, newWeight);
						break;
					case 1: 
						newWeight = oldWeight + 3 * this.HEURISTIC_FACTOR_ENEMIES_RADIUS;
						this._allNodes.put(nodeIndex, newWeight);
						break;
					case 2: 
						newWeight = oldWeight + 2 * this.HEURISTIC_FACTOR_ENEMIES_RADIUS;
						this._allNodes.put(nodeIndex, newWeight);
						break;
					case 3:
						newWeight = oldWeight + this.HEURISTIC_FACTOR_ENEMIES_RADIUS;
						this._allNodes.put(nodeIndex, newWeight);
						break;
				}			
				//this._allNodes.put(nodeIndex, newWeight);
			}
		}
		
		/*
		
		for (int nodeIndex : this._allNodes.keySet()) {
			
			ArrayList<DangerZone> dangerZoneList = Brain.GRAPHANALYSER.getDangerZonesByNodeIndex(nodeIndex);
			
			for (DangerZone dangerZone : dangerZoneList) {
				
				for (AID aid : Brain.getEnemyAIDs()) {
					
					if (aid == dangerZone._aid) {
						int weight = this._allNodes.get(nodeIndex);
						int newWeight = this.DEFAULT_HEURISTIC;
						switch (dangerZone._radius) {
							case 1: 
									newWeight = weight + this.HEURISTIC_FACTOR_ENEMIES_RADIUS;
							case 2: newWeight = weight + this.HEURISTIC_FACTOR_ENEMIES_RADIUS;
									break;
						}
						this._allNodes.put(nodeIndex, newWeight);
					}
				}
			}
		}
		*/
	}


	private void analyzeEnemiesDirection() {
		//this.HEURISTIC_FACTOR_ENEMIES_DIRECTION
		for (int nodeIndex : this._allNodes.keySet()) {
			for (AID aid : Brain.getEnemyAIDs()) {
				boolean inRange = Brain.GEOANALYSER.isInRange(aid, nodeIndex, 150);
				boolean inVision = Brain.GEOANALYSER.isInVision(aid, nodeIndex, true, 90); 
				if (inRange && inVision) {
					int weight = this._allNodes.get(nodeIndex);
					int newWeight = weight + this.HEURISTIC_FACTOR_ENEMIES_DIRECTION;
					this._allNodes.put(nodeIndex, newWeight);
				}
			}
		}
	}

}
